home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
T&A 2 the Maxx 3
/
T and A 2 The Maxx Number 3.iso
/
viewers
/
unixview
/
xgl17dta.z
/
xgl17dta
/
glib.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-24
|
8KB
|
361 lines
#ident "@(#)glib.c 1.5 91/04/01 XGRASP"
/*-
* glib.c - GRASP graphics librarian.
*
* Copyright (c) 1991 by Patrick J. Naughton
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation.
*
* This file is provided AS IS with no warranties of any kind. The author
* shall have no liability with respect to the infringement of copyrights,
* trade secrets or any patents by this file or any part thereof. In no
* event will the author be liable for any lost revenue or profits or
* other special, indirect and consequential damages.
*
* Comments and additions should be sent to the author:
*
* Patrick J. Naughton
* Sun Microsystems
* 2550 Garcia Ave, MS 10-20
* Mountain View, CA 94043
* (415) 336-1080
*
*/
#include <stdio.h>
#include <sys/types.h>
char *pname;
extern char *strrchr();
typedef struct {
char fname[14];
long offset;
long len;
char *data;
} FilenameStruct;
void
error(s1, s2, s3)
char *s1, *s2, *s3;
{
fprintf(stderr, s1, pname, s2, s3);
exit(1);
}
u_int
GetWord(fp)
FILE *fp;
{
u_char b1 = (u_char) getc(fp);
u_char b2 = (u_char) getc(fp);
return (u_int) (b1 + b2 * 256);
}
u_int
GetLong(fp)
FILE *fp;
{
u_char b1 = (u_char) getc(fp);
u_char b2 = (u_char) getc(fp);
u_char b3 = (u_char) getc(fp);
u_char b4 = (u_char) getc(fp);
return (u_int) (b1 + b2 * 256 + b3 * 256 * 256 + b4 * 256 * 256 * 256);
}
void
PutWord(fp, w)
FILE *fp;
unsigned int w;
{
unsigned char b1 = w & 255;
unsigned char b2 = (w >> 8) & 255;
putc(b1, fp);
putc(b2, fp);
}
void
PutLong(fp, l)
FILE *fp;
unsigned int l;
{
unsigned char b1 = l & 255;
unsigned char b2 = (l >> 8) & 255;
unsigned char b3 = (l >> 16) & 255;
unsigned char b4 = (l >> 24) & 255;
putc(b1, fp);
putc(b2, fp);
putc(b3, fp);
putc(b4, fp);
}
void
extractfile(in, dir, i)
FILE *in;
FilenameStruct *dir;
int i;
{
int len;
char *data;
FILE *out;
fseek(in, dir[i].offset, 0);
len = GetLong(in);
len &= 0x00ffffff;
data = (char *) malloc(len);
if (!data)
error("%s: not enough memory\n");
fread(data, len, 1, in);
out = fopen(dir[i].fname, "w");
if (!out)
error("%s: error writing: %s\n", dir[i].fname);
fwrite(data, len, 1, out);
fclose(out);
free(data);
}
void
writefile(fname, dir, nfiles)
char *fname;
FilenameStruct *dir;
int nfiles;
{
FILE *out;
int i;
long offset = 2 + (nfiles + 1) * (13 + 4);
out = fopen(fname, "w");
PutWord(out, (nfiles + 1) * (13 + 4));
for (i = 0; i < nfiles; i++) {
PutLong(out, offset);
offset += dir[i].len + 4;
fwrite(dir[i].fname, 13, 1, out);
}
PutLong(out, 0);
fwrite(" ", 13, 1, out);
for (i = 0; i < nfiles; i++) {
PutLong(out, dir[i].len);
fwrite(dir[i].data, dir[i].len, 1, out);
}
fclose(out);
}
int
findname(dir, nfiles, s)
FilenameStruct *dir;
int nfiles;
char *s;
{
int i;
if (dir)
for (i = 0; i < nfiles; i++)
if (!strcmp(dir[i].fname, s))
return i;
return -1;
}
usage()
{
error("usage: %s [-dstuea] libname [files...]\n", NULL);
}
main(argc, argv)
int argc;
char *argv[];
{
int i;
FILE *in;
FILE *out;
char *libfname;
char *opfname;
int nfiles = 0;
FilenameStruct *dir = 0;
int thefile = -1;
int c;
int dflg = 0;
int sflg = 0;
int tflg = 0;
int uflg = 0;
int eflg = 0;
int aflg = 0;
extern char *optarg;
extern int optind;
pname = argv[0];
if (argc == 1)
usage();
while ((c = getopt(argc, argv, "hd:s:t:u:e:a:")) != -1)
switch (c) {
case 'h':
printf("\nusage: glib [-dstuea] libname [files...]\n");
printf("\n where the following commands are supported:\n\n");
printf("\t-d delete file from library\n");
printf("\t-s extended file list\n");
printf("\t-t quick file list\n");
printf("\t-u update (add) file to library\n");
printf("\t-e extract file from library\n");
printf("\t-a extract all files from library\n\n");
exit(0);
case 'd':
if (uflg || eflg || aflg)
usage();
else
dflg++;
libfname = optarg;
break;
case 's':
if (tflg)
usage();
else
sflg++;
libfname = optarg;
break;
case 't':
if (sflg)
usage();
else
tflg++;
libfname = optarg;
break;
case 'u':
if (dflg || eflg || aflg)
usage();
else
uflg++;
libfname = optarg;
break;
case 'e':
if (dflg || uflg || aflg)
usage();
else
eflg++;
libfname = optarg;
break;
case 'a':
if (dflg || uflg || eflg)
usage();
else
aflg++;
libfname = optarg;
break;
default:
usage();
}
if (!libfname)
usage();
in = fopen(libfname, "r");
if (!in && !uflg)
error("%s: %s not found!\n", libfname);
if (in) {
nfiles = (GetWord(in) / 17) - 1;
dir = (FilenameStruct *) malloc(nfiles * sizeof(FilenameStruct));
for (i = 0; i < nfiles; i++) {
dir[i].offset = GetLong(in);
fread(dir[i].fname, 13, 1, in);
dir[i].fname[13] = 0;
if (dflg || eflg) {
if (!strcmp(dir[i].fname, argv[optind]))
thefile = i;
}
}
if ((dflg || eflg) && thefile == -1)
error("%s: %s not found in %s.\n", argv[optind], libfname);
if (sflg || tflg || dflg || uflg) {
if (sflg)
printf("## filename.ext\toffset\tsize\n%s",
"-- ------------\t------\t----\n");
for (i = 0; i < nfiles; i++) {
fseek(in, dir[i].offset, 0);
dir[i].len = GetLong(in);
dir[i].len &= 0x00ffffff;
if (sflg)
printf("%2d %s\t%d\t%d\n",
i, dir[i].fname, dir[i].offset, dir[i].len);
else if (tflg)
printf("%s%c", dir[i].fname,
(i + 1) % 4 && i + 1 < nfiles ? '\t' : '\n');
if (dflg || uflg) {
dir[i].data = (char *) malloc(dir[i].len);
if (!dir[i].data)
error("%s: not enough memory\n");
fread(dir[i].data, dir[i].len, 1, in);
}
}
}
}
if (eflg) {
extractfile(in, dir, thefile);
fclose(in);
} else if (aflg) {
for (i = 0; i < nfiles; i++)
extractfile(in, dir, i);
fclose(in);
} else if (dflg) {
fclose(in);
nfiles--;
for (i = thefile; i < nfiles; i++)
memcpy(&dir[i], &dir[i + 1], sizeof(FilenameStruct));
writefile(libfname, dir, nfiles);
} else if (uflg) {
if (in)
fclose(in);
for (i = optind; i < argc; i++) {
char *s = argv[i];
char *fn = strrchr(s, '/');
int n;
int idx;
fn = (fn == 0) ? s : fn + 1;
n = strlen(fn);
if (n > 13)
error("%s: '%s' is too long, must be < 13 chars.\n", s);
idx = findname(dir, nfiles, fn);
if (idx == -1) {
nfiles++;
if (!dir)
dir = (FilenameStruct *) malloc(sizeof(FilenameStruct));
else
dir = (FilenameStruct *) realloc(dir,
nfiles * sizeof(FilenameStruct));
idx = nfiles - 1;
} else
free(dir[idx].data);
memset(dir[idx].fname, 0, 14);
memcpy(dir[idx].fname, fn, n);
in = fopen(s, "r");
if (!in)
error("%s: %s not found!\n", s);
fseek(in, 0L, 2); /* eof */
dir[idx].len = ftell(in);
fseek(in, 0L, 0); /* bof */
dir[idx].data = (char *) malloc(dir[idx].len);
if (!dir[idx].data)
error("%s: not enough memory\n");
fread(dir[idx].data, dir[idx].len, 1, in);
fclose(in);
}
writefile(libfname, dir, nfiles);
}
exit(0);
}